feat(sdk): add ExecutionStore backed by DBAdapter#396
Draft
aryasaatvik wants to merge 1 commit intoRhysSullivan:mainfrom
Draft
feat(sdk): add ExecutionStore backed by DBAdapter#396aryasaatvik wants to merge 1 commit intoRhysSullivan:mainfrom
aryasaatvik wants to merge 1 commit intoRhysSullivan:mainfrom
Conversation
Adds execution history persistence to the core SDK surface, wiring
three new tables (`execution`, `execution_interaction`,
`execution_tool_call`) into `coreSchema` and exposing an
`ExecutionStore` service on `executor.executions`.
Changes:
- `core-schema.ts`: three new tables with `scope_id` / `execution_id`
/ `tool_path` / `trigger_kind` / `created_at` indexes for the runs
UI's faceting + timeline queries.
- `ids.ts`: branded `ExecutionId`, `ExecutionInteractionId`,
`ExecutionToolCallId`.
- `executions.ts`: `Execution`, `ExecutionInteraction`,
`ExecutionToolCall` Schema classes, status enums,
create/update/filter/sort/meta input types, and the
`ExecutionStore` Context.Tag.
- `execution-store.ts`: `makeExecutionStore(core)` — an
adapter-backed `ExecutionStoreService` implementation. Wraps
`typedAdapter<CoreSchema>` for CRUD, handles cursor-based
pagination, filter predicates (status, trigger, tool-path glob,
time range, code substring, hadElicitation), and builds list meta
with facets + chart buckets.
- `cursor.ts`: base64url `{ createdAt, id }` pagination cursors.
- `executor.ts`: constructs the store once per executor, exposes via
`executor.executions`.
- `executions.test.ts`: round-trip + lifecycle coverage against the
in-memory adapter (no migrations needed).
Follow-up work (future PRs in the stack):
- wire the engine to record runs + tool calls through this store,
- add `/executions` API endpoints, and
- land the runs UI.
This was referenced Apr 24, 2026
aryasaatvik
added a commit
to aryasaatvik/executor
that referenced
this pull request
Apr 24, 2026
Extends the existing `/executions` group with the three read endpoints the runs UI needs. Handlers delegate to `executor.executions.*` (added in RhysSullivan#396 / RhysSullivan#398) and scope each read to the innermost executor scope — same rule the engine applies when writing. **Endpoints:** - `GET /executions` — list with filter + cursor + optional meta. Query params: `limit`, `cursor`, `status` (CSV), `trigger` (CSV), `tool` (CSV of paths/globs), `from`/`to` (epoch ms), `after`, `code` (substring), `sort` (`<field>,<dir>`), `elicitation` (`"true"` / `"false"`). Meta bundles facets + timeline buckets; handler only asks for it when the request isn't paginated (no `cursor` / `after`), so cheap "first page, full facets" is the default call shape. - `GET /executions/:id` — single execution detail + `pendingInteraction`. 404 on unknown id via `ExecutionNotFoundError` (already declared on the group). - `GET /executions/:id/tool-calls` — tool-call timeline. 404 on unknown execution (guard rail so empty arrays don't mask typos). **Response shape:** every `Date` is serialized to epoch ms at the handler edge (`.getTime()`) so the wire format stays numeric. The schemas in `api.ts` mirror the SDK's row projections one-to-one modulo that transform. **CSV + enum handling:** `splitCsv`, `parseSortParam`, `parseElicitationParam` live in the handler file because they're edge concerns — the SDK takes typed arrays and enums. Invalid sort fields / directions drop back to defaults (no 400). No new tests — the handlers are thin wrappers over the SDK store, which already has round-trip + filter + meta coverage in `packages/core/sdk/src/executions.test.ts`. The CSV/enum parsers are small enough to validate by inspection.
aryasaatvik
added a commit
to aryasaatvik/executor
that referenced
this pull request
Apr 24, 2026
Extends the existing `/executions` group with the three read endpoints the runs UI needs. Handlers delegate to `executor.executions.*` (added in RhysSullivan#396 / RhysSullivan#398) and scope each read to the innermost executor scope — same rule the engine applies when writing. **Endpoints:** - `GET /executions` — list with filter + cursor + optional meta. Query params: `limit`, `cursor`, `status` (CSV), `trigger` (CSV), `tool` (CSV of paths/globs), `from`/`to` (epoch ms), `after`, `code` (substring), `sort` (`<field>,<dir>`), `elicitation` (`"true"` / `"false"`). Meta bundles facets + timeline buckets; handler only asks for it when the request isn't paginated (no `cursor` / `after`), so cheap "first page, full facets" is the default call shape. - `GET /executions/:id` — single execution detail + `pendingInteraction`. 404 on unknown id via `ExecutionNotFoundError` (already declared on the group). - `GET /executions/:id/tool-calls` — tool-call timeline. 404 on unknown execution (guard rail so empty arrays don't mask typos). **Response shape:** every `Date` is serialized to epoch ms at the handler edge (`.getTime()`) so the wire format stays numeric. The schemas in `api.ts` mirror the SDK's row projections one-to-one modulo that transform. **CSV + enum handling:** `splitCsv`, `parseSortParam`, `parseElicitationParam` live in the handler file because they're edge concerns — the SDK takes typed arrays and enums. Invalid sort fields / directions drop back to defaults (no 400). No new tests — the handlers are thin wrappers over the SDK store, which already has round-trip + filter + meta coverage in `packages/core/sdk/src/executions.test.ts`. The CSV/enum parsers are small enough to validate by inspection.
aryasaatvik
added a commit
to aryasaatvik/executor
that referenced
this pull request
Apr 24, 2026
Extends the existing `/executions` group with the three read endpoints the runs UI needs. Handlers delegate to `executor.executions.*` (added in RhysSullivan#396 / RhysSullivan#398) and scope each read to the innermost executor scope — same rule the engine applies when writing. **Endpoints:** - `GET /executions` — list with filter + cursor + optional meta. Query params: `limit`, `cursor`, `status` (CSV), `trigger` (CSV), `tool` (CSV of paths/globs), `from`/`to` (epoch ms), `after`, `code` (substring), `sort` (`<field>,<dir>`), `elicitation` (`"true"` / `"false"`). Meta bundles facets + timeline buckets; handler only asks for it when the request isn't paginated (no `cursor` / `after`), so cheap "first page, full facets" is the default call shape. - `GET /executions/:id` — single execution detail + `pendingInteraction`. 404 on unknown id via `ExecutionNotFoundError` (already declared on the group). - `GET /executions/:id/tool-calls` — tool-call timeline. 404 on unknown execution (guard rail so empty arrays don't mask typos). **Response shape:** every `Date` is serialized to epoch ms at the handler edge (`.getTime()`) so the wire format stays numeric. The schemas in `api.ts` mirror the SDK's row projections one-to-one modulo that transform. **CSV + enum handling:** `splitCsv`, `parseSortParam`, `parseElicitationParam` live in the handler file because they're edge concerns — the SDK takes typed arrays and enums. Invalid sort fields / directions drop back to defaults (no 400). No new tests — the handlers are thin wrappers over the SDK store, which already has round-trip + filter + meta coverage in `packages/core/sdk/src/executions.test.ts`. The CSV/enum parsers are small enough to validate by inspection.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stack
Root of a 5-PR stack — merge first. Cross-fork GitHub PRs can't use a branch on a contributor fork as a base, so these five PRs display as independent in the UI. The real dependency chain is the commit graph.
feat(sdk): ExecutionStore backed by DBAdapterfeat(execution): persist engine runs + tool callsfeat(execution): trigger propagation (CLI/HTTP/MCP)feat(apps): execution tables in drizzle schemasfeat(api): /executions list/get/tool-calls endpointsEach subsequent PR's diff includes this one's commits until this lands — after that the diffs cleanly separate.
Summary
Adds execution history persistence as a first-class concern of the SDK, wiring three tables into
coreSchema(execution,execution_interaction,execution_tool_call) and exposing anExecutionStoreservice onexecutor.executions. Generic — every backend that implements theDBAdaptercontract (sqlite, postgres, memory) inherits the store for free.What this PR adds
core-schema.ts: three new tables with indexes onscope_id,execution_id,tool_path,trigger_kind,created_atto back runs UI facets + timeline queries.ids.ts: brandedExecutionId,ExecutionInteractionId,ExecutionToolCallId.executions.ts:Execution/ExecutionInteraction/ExecutionToolCallSchema classes, status enums, create/update/list/filter input types, and theExecutionStoreContext.Tag.execution-store.ts:makeExecutionStore(core)— adapter-backed implementation. Cursor pagination (cursor.ts), filter predicates (status/trigger/tool-glob/time/code/hadElicitation), and meta aggregation (facets + chart buckets).executor.ts: constructs the store once per executor, exposed viaexecutor.executions.executions.test.ts: round-trip + lifecycle coverage against the in-memory adapter.What this PR does NOT do
Follow-up PRs in the stack will:
executor.executions.create/update/record*/finish*on execute/resume/tool-invoke boundaries (feat(execution): persist engine runs + tool calls via ExecutionStore #398)./executionsHTTP API endpoints (feat(api): /executions list, get, tool-calls endpoints #401).Test plan
bun x vitest run— all 97 SDK tests pass, including 7 newexecutions.test.tscases.bun x tsc --noEmit— zero type errors in@executor/sdk.connectionsprecedent inexecutor.ts.